<template>
  <el-dialog v-if="windowOpen" append-to-body :before-close="closeWindow" :visible.sync="windowOpen" width="1200px" top="15vh">
    <template #title>
      <div id="detail-header">
        <div class="text-box">
          <div class="number">P{{windowData.number}}</div>
        </div>
        <div class="btn-box">
          <el-button size="small" @click.stop="translateImg">一键标记</el-button>
          <el-button size="small" @click.stop="ocrCheckImg">校准标记</el-button>
        </div>
      </div>
    </template>
    <div id="detail-container">
      <div class="container">
        <!--  功能选项区域  -->
        <div class="left">
          <el-tooltip effect="dark" placement="right" content="保存">
            <el-button class="btn" circle
                       @click.stop="saveMark"><i class="save"/></el-button>
          </el-tooltip>
          <el-tooltip effect="dark" placement="right" :content="MODE_OPTIONS.VIEW.text">
            <el-button class="btn" type="warning" icon="el-icon-view" :plain="mode !== MODE_OPTIONS.VIEW.code" circle
                       @click.stop="switchMode(MODE_OPTIONS.VIEW)"></el-button>
          </el-tooltip>
          <el-tooltip effect="dark" placement="right" :content="MODE_OPTIONS.MARK.text">
            <el-button class="btn" type="success" icon="el-icon-plus" :plain="mode !== MODE_OPTIONS.MARK.code" circle
                       @click.stop="switchMode(MODE_OPTIONS.MARK)"></el-button>
          </el-tooltip>
          <el-tooltip effect="dark" placement="right" :content="MODE_OPTIONS.MOVE.text">
            <el-button class="btn" type="success" icon="el-icon-rank" :plain="mode !== MODE_OPTIONS.MOVE.code" circle
                       @click.stop="switchMode(MODE_OPTIONS.MOVE)"></el-button>
          </el-tooltip>
          <el-tooltip effect="dark" placement="right" :content="MODE_OPTIONS.EDIT.text">
            <el-button class="btn" type="primary" icon="el-icon-edit" :plain="mode !== MODE_OPTIONS.EDIT.code" circle
                       @click.stop="switchMode(MODE_OPTIONS.EDIT)"></el-button>
          </el-tooltip>
          <el-tooltip effect="dark" placement="right" :content="MODE_OPTIONS.CHECK.text">
            <el-button class="btn" type="danger" icon="el-icon-s-check" :plain="mode !== MODE_OPTIONS.CHECK.code"
                       circle
                       @click.stop="switchMode(MODE_OPTIONS.CHECK)"></el-button>
          </el-tooltip>
          <el-tooltip effect="dark" placement="right" content="重置">
            <el-button class="btn" type="info" icon="el-icon-refresh-left" plain circle
                       @click.stop="reset"></el-button>
          </el-tooltip>
          <el-popover placement="right" v-model="rmBtnVisible">
            <p style="align-items: center">确定要清空标记吗？</p>
            <div style="text-align: right;padding-top: 5px; margin: 0">
              <el-button size="mini" type="text" @click.stop="rmBtnVisible = false">取消</el-button>
              <el-button type="danger" size="mini" @click.stop="clearMarks">确定</el-button>
            </div>
            <el-button slot="reference" class="btn" type="danger" icon="el-icon-delete" plain circle></el-button>
          </el-popover>
          <el-popover style="margin-top: auto"
                      title="快捷键提示"
                      placement="right"
                      trigger="hover">
            <div style="display: flex; flex-direction: column; font-size: small">
              <span><button id="key-button">Ctrl</button> + <button id="key-button"><i class="el-icon-right"/></button> 跳转下一页</span>
              <span><button id="key-button">Ctrl</button> + <button id="key-button"><i class="el-icon-back"/></button> 跳转上一页</span>
              <span><button id="key-button">Ctrl</button> + <button id="key-button"><i class="el-icon-top"/></button> 上一个标记</span>
              <span><button id="key-button">Ctrl</button> + <button id="key-button"><i class="el-icon-bottom"/></button> 下一个标记</span>
              <span><button id="key-button">Ctrl</button> + <button id="key-button">S</button> 保存标记</span>
              <span style="font-size: smaller; opacity: 0.5">※ 聚焦输入框生效</span>
            </div>
            <el-button slot="reference" class="btn" icon="el-icon-question" plain circle></el-button>
          </el-popover>
        </div>
        <!--  图源编辑区域  -->
        <div class="main">
          <image-zoom ref="ImageIndex" :imgUrl="windowData.imageUrl" :markList="markList" :mode="mode"
                      :focusOn="focusOn"
                      @initXY="initXY"
                      @addMark="addMark"
                      @focusMark="focusMark"
                      @removeMark="removeMark"
                      @updateMark="updateMark"
                      v-loading="loadingFlag"
          />
          <span v-if="currentIndex !== 0" class="el-icon-caret-left left-icon-box icon-box" @click="toLast"/>
          <span v-if="currentIndex !== indexMax" class="el-icon-caret-right right-icon-box icon-box" @click="toNext"/>
        </div>
        <!--  右侧信息展示区域  -->
        <div class="right">
          <div class="header">
            <h4 style="display: flex; align-items: center; justify-content: space-between"
                @click="showMoreMember = !showMoreMember">坑组人员
              <i :class="{'el-icon-arrow-down' : !showMoreMember, 'el-icon-arrow-up' : showMoreMember}"/>
            </h4>
            <el-collapse-transition>
              <div v-if="showMoreMember">
                <div class="member-box" v-for="(item) in staffList" :key="item.key">
                  <span class="keyName">{{ item.key }}：</span>
                  <span>{{ item.value }}</span>
                </div>
              </div>
            </el-collapse-transition>
          </div>
          <div class="mark-box" v-loading="loadingFlag">
            <empty-box v-if="markList.length === 0" tip="快开始吧"/>
            <draggable v-else v-model="markList" animation="500" chosenClass="chosen"
                       @change="() => this.editFlag = true">
                <div class="markList-item" v-for="(mark, index) in markList" :key="index"
                     @click="focusMark(mark)"
                     :class="{
                     'highlight' : mark.number === focusOn,
                      'warning': mark.textAmend && mark.text !== mark.textAmend
                   }">
                  <span class="index">{{ index + 1 }}</span>
                  <el-divider direction="vertical"/>
                  <span class="text text-ellipsis">
                  {{ mode === MODE_OPTIONS.EDIT.code ? mark.text : !mark.textAmend ? mark.text : mark.textAmend }}
              </span>
                  <span class="btn btn-hidden el-icon-copy-document" v-if="mode === MODE_OPTIONS.VIEW.code"
                        @click.stop="copyToClipboard(mark)"></span>
                  <el-popover placement="left" width="300">
                    <div id="comment-box">
                      <div class="comment-area">
                        <div class="comment" v-for="(item) in commentList" :key="item.id">
                          <div class="header">
                            <div class="name text-ellipsis">{{ item.userName }}</div>
                            <div class="time">{{ item.createTime }}</div>
                          </div>
                          <div class="text">{{ item.comment }}</div>
                          <div class="del-box" v-if="item.owner" @click.stop="undoCommentMark(item)">
                            <i class="el-icon-delete"></i></div>
                        </div>
                      </div>
                      <div class="input-area">
                        <el-input clearable placeholder="输入留言" v-model="comment"></el-input>
                        <el-button icon="el-icon-s-promotion" style="margin-left: 10px;" type="warning" size="mini"
                                   @click.stop="commentMark(mark)"></el-button>
                      </div>
                    </div>
                    <span slot="reference"
                          class="btn el-icon-message-solid"
                          :class="{'btn-show': mark.notice, 'btn-hidden' : !mark.notice }"
                          @click.stop="openComment(mark.markId)"></span>
                  </el-popover>
                  <span class="btn btn-hidden el-icon-delete" @click.stop="removeMark(mark)"></span>
                </div>
            </draggable>
          </div>
          <el-input ref="input" type="textarea" :autosize="{minRows: 5, maxRows: 5}" placeholder="请输入内容"
                    v-model="textarea"
                    :disabled="mode === MODE_OPTIONS.VIEW.code || mode === MODE_OPTIONS.MOVE.code"
                    @input="markEdit" @keydown.native="onKeyDownHandler"/>
        </div>
      </div>
    </div>
  </el-dialog>
</template>
<script>
import ImageZoom from "@/components/mgWindow/imageZoom.vue";
import {comment, markList, queryComment, saveMark, undoComment} from "@/api/mgEditApi";
import {ocrCheck, translate} from "@/api/mgAiApi";
import draggable from "vuedraggable";

export default {
  name: "editWindow",
  props: ['indexMax', 'memberList'],
  components: {draggable, ImageZoom},
  data() {
    return {
      windowOpen: false,
      windowData: {},
      currentIndex: 0,
      editFlag: false,
      loadingFlag: true,
      focusOn: '',
      MODE_OPTIONS: {
        VIEW: {code: 1, text: '浏览模式'},
        MARK: {code: 2, text: '标记模式'},
        EDIT: {code: 3, text: '翻译模式'},
        CHECK: {code: 4, text: '校对模式'},
        MOVE: {code: 5, text: '移动模式'}
      },
      mode: 0,
      textarea: "",  // 输入框绑定的值
      rmBtnVisible: false,
      showMoreMember: false,
      markList: [],
      comment: '',
      commentList: []
    }
  },
  computed: {
    staffList() {
      const group = {}
      const staffList = []
      // 按职位分组
      this.memberList.forEach((item) => {
        // 遍历职位
        item.positionName.forEach((position) => {
          // 如果数组中不存在职位则添加
          if (!group[position.value]) {
            group[position.value] = []
          }
          // 将人员添加到职位数组中
          group[position.value].push(item.userName)
        })
      })
      // 再重组成数组
      for (const position in group) {
        staffList.push({
          key: position,
          value: group[position].join(', ')
        })
      }
      return staffList
    }
  },
  methods: {
    ocrCheck,
    undoComment,
    /**
     * 初始化标记列表
     */
    async initMarkList(epRid) {
      let res = await markList(epRid)
      this.markList = res.data
      this.loadingFlag = false
    },
    /**
     * 改变xy的位置
     * @param scale 缩放比例
     */
    initXY(scale) {
      this.$nextTick(() => {
        this.markList.forEach((item) => {
          item.x = item.x * scale.toFixed(2)
          item.y = item.y * scale.toFixed(2)
        })
      })
    },
    /**
     * 删除标记
     * @param mark 标记
     */
    removeMark(mark) {
      this.markList = this.markList.filter(item => item.number !== mark.number)
    },
    /**
     * 添加标记
     * @param mark 标记
     */
    addMark(mark) {
      this.markList.push(mark)
      this.textarea = ''
      // 聚焦
      this.focusMark(mark)
    },
    /**
     * 更新了标记
     */
    updateMark() {
      this.editFlag = true;
    },
    /**
     * 编辑标记
     */
    markEdit() {
      if (this.focusOn !== '') {
        const index = this.markList.findIndex((item) => item.number === this.focusOn)
        if (index !== -1) {
          let item = this.markList[index]
          switch (this.mode) {
              // 校对模式修改校对文本
            case this.MODE_OPTIONS.CHECK.code:
              item.textAmend = this.textarea;
              break;
              // 打点和翻译模式修改翻译文本
            case this.MODE_OPTIONS.MARK.code:
            case this.MODE_OPTIONS.EDIT.code:
              item.text = this.textarea;
              break;
          }
          this.$set(this.markList, index, item)
        }
      }
    },
    /**
     * 处理标记顺序
     */
    handleMarkNumber() {
      this.markList.forEach((item, index) => {
        item.number = index + 1
      })
    },
    copyToClipboard(mark) {
      let text = this.handleShowText(mark)
      // 添加一个input元素放置需要的文本内容
      const data = document.createElement('input')
      data.value = text
      document.body.appendChild(data)
      // 选中并赋值文本到剪切板
      data.select()
      document.execCommand('copy')
      // 移除input元素
      document.body.removeChild(data)
      this.$notify({
        title: '复制成功',
        type: 'success'
      })
    },
    /**
     * 打开窗口
     * @param index 当前下标
     * @param windowData 当前窗口数据
     */
    openWindow(index, windowData) {
      this.windowOpen = true
      this.flashData(index, windowData)
    },
    /**
     * 刷新数据
     * @param index 当前下标
     * @param windowData 当前窗口数据
     */
    flashData(index, windowData) {
      this.windowData = windowData
      this.currentIndex = index
      this.loadingFlag = true
      this.initMarkList(windowData.epRid)
      this.reset()
      // 初始化标记修改标识
      this.editFlag = false
    },
    /**
     * 关闭窗口
     */
    closeWindow() {
      this.windowOpen = false
      this.handleAndSaveMark()
    },
    /**
     * 主动保存标记
     */
    saveMark() {
      // 判断是否修改过标记
      if (this.editFlag) {
        this.handleMarkNumber()
        saveMark(this.windowData.epRid, this.markList).then(() => {
          this.initMarkList(this.windowData.epRid)
          this.editFlag = false
        });
      }
    },
    /**
     * 处理标记并保存
     */
    handleAndSaveMark() {
      // 判断是否修改过标记
      if (this.editFlag) {
        this.handleMarkNumber()
        saveMark(this.windowData.epRid, this.markList);
      }
    },
    /**
     * 翻译图片
     */
    translateImg() {
      this.loadingFlag = true
      translate(this.windowData.epRid).then((res) => {
        if (res.code === '200') {
          this.$message({
            message: '翻译成功',
            type: 'success'
          })
          this.initMarkList(this.windowData.epRid)
        }
      }).finally(() => {
        this.loadingFlag = false
      })
    },
    /**
     * 校准OCR识别
     */
    ocrCheckImg() {
      this.saveMark()
      ocrCheck(this.windowData.epRid).then((res) => {
        if (res.code === '200') {
          this.$message({
            message: '校准完毕，感谢数据提供~',
            type: 'success'
          })
        }
      })
    },
    /**
     * 查询留言
     * @param markId 标记id
     */
    openComment(markId) {
      this.comment = ''
      if (markId) {
        this.flashComment(markId)
      }
    },
    /**
     * 留言
     */
    commentMark(mark) {
      // 判断留言是否为空
      if (this.comment === '') return
      if (mark.markId === undefined) {
        this.$message({message: '请先保存标记', type: 'warning'})
      } else {
        // 有id则直接留言
        comment(mark.markId, this.comment).then((res) => {
          if (res.code === '200') {
            this.$message({
              message: '留言成功',
              type: 'success'
            })
            this.comment = ''
            this.flashComment(mark.markId)
          }
        })
      }
    },
    /**
     * 撤销留言
     * @param item 留言
     */
    undoCommentMark(item) {
      if (item.id == null) return
      undoComment(item.id).then((res) => {
        if (res.code === '200') {
          this.flashComment(item.markId)
        }
      })
    },
    /**
     * 刷新留言
     * @param markId 标记id
     */
    flashComment(markId) {
      queryComment(markId).then(res => {
        if (res.code === '200') {
          this.commentList = res.data
        }
      })
    },
    toLast() {
      // 先保存再切换
      this.handleAndSaveMark()
      this.$emit('toLast')
    },
    toNext() {
      // 先保存再切换
      this.handleAndSaveMark()
      this.$emit('toNext')
    },
    /**
     * 聚焦标记
     * @param mark 标记
     */
    focusMark(mark) {
      this.focusOn = mark.number;
      this.textarea = this.handleShowText(mark)
      this.$refs.input.focus()
    },
    /**
     * 切换模式
     * @param mode 模式
     */
    switchMode(mode) {
      this.rmBtnVisible = false
      this.mode = mode.code
      let title = mode.text
      let msg = ''
      switch (mode) {
        case this.MODE_OPTIONS.MARK :
          msg = '左键标记，右键删除';
          break;
        case this.MODE_OPTIONS.MOVE :
          msg = '可以拖动标记';
          break;
      }
      this.$notify({
        title: title,
        message: msg,
        type: 'success',
        showClose: false,
        position: "top-left",
        duration: 2000
      })
    },
    /**
     * 键盘事件
     * @param event 事件
     */
    onKeyDownHandler(event) {
      // 监听Ctrl 和 → 键
      if (event.ctrlKey && event.key === 'ArrowRight') {
        this.toNext()
      }
      // 监听Ctrl 和 ← 键
      if (event.ctrlKey && event.key === 'ArrowLeft') {
        this.toLast()
      }
      // 监听Ctrl 和 ↑ 键
      if (event.ctrlKey && event.key === 'ArrowUp' && this.focusOn !== '') {
        const index = this.markList.findIndex((item) => item.number === this.focusOn)
        if (index > 0) {
          this.focusMark(this.markList[index - 1])
        }
      }
      // 监听Ctrl 和 ↓ 键
      if (event.ctrlKey && event.key === 'ArrowDown') {
        const index = this.markList.findIndex((item) => item.number === this.focusOn)
        if (index < this.markList.length - 1) {
          this.focusMark(this.markList[index + 1])
        }
      }
      // 监听Ctrl 和 S 键
      if (event.ctrlKey && event.key.toLowerCase() === 's') {
        // 阻止默认事件
        event.preventDefault()
        this.saveMark()
      }
    },
    handleShowText(mark) {
      return this.mode === this.MODE_OPTIONS.EDIT.code ? mark.text : !mark.textAmend ? mark.text : mark.textAmend
    },
    clearMarks() {
      this.markList.splice(0, this.markList.length)
      this.rmBtnVisible = false
    },
    reset() {
      this.focusOn = ''
      this.$nextTick(() => {
        this.$refs.ImageIndex.initImg()
      })
      this.textarea = ''
    }
  },
  mounted() {
    this.mode = this.MODE_OPTIONS.VIEW.code
  },
  watch: {
    markList: {
      handler(newVal, oldVal) {
        // 不知道为什么，未修改的时候，newVal和oldVal是不等的，修改后反而相等，所以这里取===
        if (newVal === oldVal) {
          this.editFlag = true
        }
      }
    }
  }
}
</script>
<style scoped lang="scss">
::v-deep .el-dialog__body {
  padding: 0 0 20px !important;
}

@import url("@/scss/editWindow.scss");
</style>